package net.qunzhi.modules.cms.service.impl;

import com.alibaba.fastjson.JSON;
import net.qunzhi.common.utils.*;
import net.qunzhi.modules.app.dto.WXLogDto;
import net.qunzhi.modules.app.entity.AppTbAlarmRecordConfirmEntity;
import net.qunzhi.modules.app.service.AppTbAlarmRecordConfirmService;
import net.qunzhi.modules.cms.dao.TbAlarmRecordDao;
import net.qunzhi.modules.cms.entity.TbAlarmRecordEntity;
import net.qunzhi.modules.cms.entity.TbUserInfoEntity;
import net.qunzhi.modules.cms.service.*;
import net.qunzhi.modules.cms.vo.MonitorVO;
import net.qunzhi.modules.cms.websocket.WebSocketServer;
import net.qunzhi.modules.sys.entity.SysUserEntity;
import net.qunzhi.modules.sys.service.SysUserService;
import net.qunzhi.modules.weixin.service.PushWxMessageService;
import org.apache.catalina.User;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import net.qunzhi.modules.cms.dao.TbAlarmMonitorDao;
import net.qunzhi.modules.cms.entity.TbAlarmMonitorEntity;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;


@Service("tbAlarmMonitorService")
public class TbAlarmMonitorServiceImpl extends ServiceImpl<TbAlarmMonitorDao, TbAlarmMonitorEntity> implements TbAlarmMonitorService {

    @Autowired private DzFlowDataService dzFlowDataService;
    @Autowired private XjFlowDataService xjFlowDataService;
    @Autowired private TbAlarmRecordService alarmRecordService;
    @Autowired private AppTbAlarmRecordConfirmService alarmRecordConfirmService;
    @Autowired private TbAlarmRecordDao alarmRecordDao;
    @Autowired private WebSocketServer webSocketServer;
    @Autowired private SysUserService sysUserService;
    @Autowired private TbUserInfoService tbUserInfoService;
    @Autowired private PushWxMessageService pushWxMessageService;

    @Override
    public PageUtils queryPage(BaseQuery query) {
        IPage<TbAlarmMonitorEntity> page = this.page(
                new Query<TbAlarmMonitorEntity>().getPage(query),
                new QueryWrapper<TbAlarmMonitorEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<MonitorVO> queryMonitorList() {
        List<MonitorVO> list = baseMapper.queryMonitorList();
        // 装入丹灶的获取数据
        List<MonitorVO> dzList = dzFlowDataService.getMonitorData(list.stream().filter(recordVO -> recordVO.getType().equals(Constant.EquipmentType.DZ.getCode())).collect(Collectors.toList()));
        // 装入西江的获取数据
        List<MonitorVO> xjList = xjFlowDataService.getMonitorData(list.stream().filter(recordVO -> recordVO.getType().equals(Constant.EquipmentType.XJ.getCode())).collect(Collectors.toList()));
        List<MonitorVO> collect = list.stream().filter(recordVO -> recordVO.getType().equals(Constant.EquipmentType.SPIDER.getCode())).collect(Collectors.toList());
        collect.addAll(dzList);
        collect.addAll(xjList);
        return collect.stream().sorted(Comparator.comparing(MonitorVO::getEquipmentId)).collect(Collectors.toList());
    }

    @Override
    public void doAlarmMonitorTask() {
        List<MonitorVO> monitorVOS = queryMonitorList();
        for (MonitorVO vo : monitorVOS) {
            String description = null;
            if (Constant.ONE==vo.getIsFlowAlarm() && null != vo.getFlowValue()) {
                if (null!=vo.getFlowLowerLimit() && vo.getFlowValue().compareTo(vo.getFlowLowerLimit())<0) {
                    description = addDescription(description, Constant.AlarmDescription.FLOW_LOWER.getName());
                } else if (null!=vo.getFlowUpperLimit() && vo.getFlowValue().compareTo(vo.getFlowUpperLimit())>0) {
                    description = addDescription(description, Constant.AlarmDescription.FLOW_UPPER.getName());
                }
            } if (Constant.ONE==vo.getIsPressAlarm() && null != vo.getPressValue()) {
                if (null!=vo.getPressValue() && vo.getPressValue().compareTo(vo.getPressLowerLimit())<0) {
                    description = addDescription(description, Constant.AlarmDescription.PRESS_LOWER.getName());
                } else if (null!=vo.getPressValue() && vo.getPressValue().compareTo(vo.getPressUpperLimit())>0) {
                    description = addDescription(description, Constant.AlarmDescription.PRESS_UPPER.getName());
                }
            } if (Constant.ONE==vo.getIsOutageAlarm() && null != vo.getStatus() && vo.getStatus().equals(0)) {
                description = addDescription(description, Constant.AlarmDescription.FLOW_LOWER.getName());
            }
            if (StringUtils.isNotBlank(description)) {
                addAlarmMonitor(vo, description);
            }
        }
    }

    private String addDescription(String description, String name) {
        if (StringUtils.isNotBlank(description)) {
            return description + "," + name;
        }
        return name;
    }

    /**
     * 保存报警记录
     * @param vo
     * @param description
     */
    private void addAlarmMonitor(MonitorVO vo, String description) {
        TbAlarmRecordEntity alarmRecordEntity = new TbAlarmRecordEntity();
        BeanUtils.copyProperties(vo, alarmRecordEntity);
        alarmRecordEntity.setDescription(description).setCreateTime(LocalDateTime.now());
        alarmRecordDao.insert(alarmRecordEntity);
        // 推送管理端
        try {
            webSocketServer.sendMessageAll(JSON.toJSONString(alarmRecordEntity));
        } catch (IOException e) {
            log.error("推送后台用户失败，错误：{}", e);
        }
        // 新建报警待确认记录并推送到微信端
        List<TbUserInfoEntity> list = tbUserInfoService.list(new QueryWrapper<TbUserInfoEntity>()
                .eq("status", Constant.ZERO)
                .eq("is_alarm", Constant.ONE));// 激活正常且符合接收的用户列表
        WXLogDto wxLogDto = new WXLogDto().setCreateTime(LocalDateUtils.dateFormat(alarmRecordEntity.getCreateTime(), LocalDateUtils.DATE_TIME_PATTERN)).setTitle("您有一个新的报警提示").setContent(alarmRecordEntity.getDescription());
        list.forEach(user -> {
            var alarmRecordConfirmEntity = new AppTbAlarmRecordConfirmEntity()
                    .setUserId(user.getId())
                    .setAlarmRecordId(alarmRecordEntity.getId());
            alarmRecordConfirmService.save(alarmRecordConfirmEntity);
            pushWxMessageService.sendAlarmRemind(user.getOpenId(), wxLogDto, alarmRecordEntity.getId());
        });
    }

}